#include <click/config.h>
#include <click/confparse.hh>
#include <click/error.hh>
#include <click/glue.hh>
#include <click/straccum.hh>
#include <clicknet/ether.h>
#include <clicknet/llc.h>
#include <clicknet/wifi.h>
#include <elements/wifi/bitrate.hh>
#include "morebatch.hh"

CLICK_DECLS

uint MOREBatch::Config::txtime() const {
    if(_txtime == 0) {
        _txtime = calc_usecs_wifi_packet_tries(
               datasize 
               + k + sizeof(more_block)
               + sizeof(more_data)+sizeof(more_pkt)+sizeof(click_ether),
               rate, 0, 0); // includes sifs?
        click_chatter("COMPUTED TXTIME for %d bytes at rate %d = %d\n",
                datasize, rate, _txtime);
    }
    return _txtime;
}

bool MOREBatch::decode(Packet *p) {
    if(_D.add(new CodedBlock(p, true))) {
        if(DEBUG_RANK)
            click_chatter("%d D Rank %d\n", _seqno, _D.rank());
        return true;
    }
    return false;
}

bool MOREBatch::forward(Packet *p) {
    if(_M.addI(new CodedBlock(p, true))) {
        if(DEBUG_RANK)
            click_chatter("%d Q Rank %d\n", _seqno, _M.rank());
        return true;
    }
    return false;
}

void MOREBatch::source(WritablePacket *p) {
#if 0
// FIXME: we'll source real packet later
    CodedBlock *cb = new CodedBlock(_M.k(), _c.datasize);
    if(DEBUG_RANK)
        click_chatter("SOURCE %d : %d / %d\n", _seqno, _M.Irank(), _M.k());
    cb->source(_M.rank(), p);
#endif
    CodedBlock *cb = new CodedBlock(_c.k, _M.rank(), _c.datasize, p);
    _M.addI(cb);
}

WritablePacket * MOREBatch::take() {
    assert(queued());
    assert(_c.rate > 0);

    // finalize: write up the coefficients
    WritablePacket *p = _M.take();
    p->push(sizeof(more_data));
    more_data *md = (more_data *)p->data();
    md->_metric = _c.metric;
    md->_tx = _tx;
    ++_tx;
    return p;
}


CLICK_ENDDECLS
ELEMENT_PROVIDES(MOREBatch)
